home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / libwais / ir / irbuild.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  33.7 KB  |  950 lines

  1.  
  2. /* WIDE AREA INFORMATION SERVER SOFTWARE:
  3.    No guarantees or restrictions.  See the readme file for the full standard
  4.    disclaimer.
  5.  
  6.    Brewster@think.com
  7. */
  8.  
  9. #ifndef lint
  10. static char *RCSid = "$Header: /y/src/wais/wais-8-b5/ir/RCS/irbuild.c,v 1.47.1.1 1992/07/11 01:01:21 curtisg Exp curtisg $";
  11. #endif
  12.  
  13. /*
  14.  * Building an index with a Unix shell interface.
  15.  *
  16.  * -brewster 6/90
  17.  */
  18.  
  19. /* Change log:
  20.  * added -stdio option from jik@athena.mit.edu
  21.  * $Log: irbuild.c,v $
  22.  *
  23.  * M000, 28-May-93, hess
  24.  * mods for ERG database files.
  25.  * same as mail type, but bails out after ~200 lines, avoids large, large
  26.  * indexes..., since many times the "From " portion of the file is indented
  27.  * our mail threads look like one large piece of mail, which is ok, they 
  28.  * are intended to be read as a whole. But we still need to make sure 
  29.  * they are'nt broken up, so never let the seperator routine return true
  30.  *
  31.  * Revision 1.47.1.1  1992/07/11  01:01:21  curtisg
  32.  * Changes for SCO UNIX
  33.  *
  34.  * Revision 1.47  92/05/10  14:48:17  jonathan
  35.  * Updated for release.
  36.  * 
  37.  * Revision 1.46  92/05/08  10:03:17  jonathan
  38.  * Adjusted memory paramters.  It's closer...
  39.  * 
  40.  * Revision 1.45  92/05/06  17:26:46  jonathan
  41.  * Added switch for indexing contents, new user-specified type name, new type:
  42.  * filename, which only puts the name of the file in the header.
  43.  * 
  44.  * Revision 1.44  92/04/25  21:14:35  brewster
  45.  * added ziff
  46.  * 
  47.  * Revision 1.43  92/04/22  15:29:13  jonathan
  48.  * Added jargon to usage message.
  49.  * 
  50.  * Revision 1.42  92/04/01  17:08:50  jonathan
  51.  * Added FTP type.
  52.  * 
  53.  * Revision 1.41  92/03/25  18:49:39  jonathan
  54.  * Added log_level and log_file arguments.
  55.  * 
  56.  * Revision 1.40  92/03/22  18:38:14  brewster
  57.  * added objective C filter
  58.  * 
  59.  * Revision 1.39  92/03/20  11:02:44  jonathan
  60.  * Added code to handle switches for word_pairs and word_postition info.
  61.  * 
  62.  * Revision 1.38  92/03/17  07:34:32  jonathan
  63.  * Fixed spacing in usage message.
  64.  * 
  65.  * Revision 1.37  92/03/10  10:42:51  morris
  66.  * fixed small bug in command line argument handleing.  doesn't die if there
  67.  * are no args.
  68.  * 
  69.  * Revision 1.36  92/03/05  07:05:32  shen
  70.  * add cm grow percent and textsize to command line and init search engine
  71.  * 
  72.  * Revision 1.35  92/03/04  16:34:09  jonathan
  73.  * Set wais_pid from getpid().
  74.  * 
  75.  * Revision 1.34  92/02/20  09:49:37  jonathan
  76.  * Added bibtex and nhyp filters from S.P.vandeBurgt@research.ptt.nl.
  77.  * 
  78.  * Revision 1.33  92/02/17  14:21:08  jonathan
  79.  * Added switch to disable creation of catalog (-nocat).
  80.  * 
  81.  * Revision 1.32  92/02/17  12:41:55  jonathan
  82.  * Added RCSid.
  83.  * 
  84.  * Revision 1.31  92/02/17  12:41:01  jonathan
  85.  * Build catalog after completion of indexing.
  86.  * 
  87.  * Revision 1.30  92/02/12  13:22:53  jonathan
  88.  * Added "$Log" so RCS will put the log message in the header
  89.  * 
  90.  */
  91.  
  92. /* to do:
  93.  *   done: make incremental indexing not index things that are already index
  94.  *   add extra arg -register that will send in description of the server to 
  95.  *           the directory of servers.
  96.  *   done: create a source struct in the .src file
  97.  *   make it continuously index to keep itself uptodate.
  98.  *
  99.  */
  100.  
  101. #include <string.h>
  102. #include <sys/types.h>
  103. #include <sys/param.h>
  104. #include <sys/stat.h>
  105. #include "irdirent.h"
  106. #include "cutil.h"
  107. #include "futil.h"
  108. #include "irfiles.h"
  109. #include "irtfiles.h"
  110. #include "panic.h"
  111. #include "ircfiles.h"
  112. #include "version.h"
  113. #include "irext.h"
  114.  
  115. #define INDEXER_DATE "Sun May 10 1992"
  116.  
  117. /* for reporting errors, in WAIStation it is defined in CRetrievalApp.c */
  118.  
  119. extern boolean indexingForBeta;
  120.  
  121. struct file_type {
  122.     char *name;
  123.     char *description;
  124.     char *type;
  125.     boolean (*separator_function)();
  126.     void (*header_function)();
  127.     long (*date_function)();
  128.     void (*finish_header_function)();
  129.     boolean index_contents;
  130. } file_type_list[] = {
  131.     {"groliers",
  132.     "groliers encyclopedia special format",
  133.     "TEXT", groliers_separator_function, groliers_header_function, 0, groliers_finish_header_function, 1},
  134. #ifdef NEXT
  135.     {"objc",
  136.     "objective-C .h and .m files",
  137.     "TEXT", qobjc_separator_function, wobj_header_function, 0, wobj_finish_header_function, 1},
  138. #endif /* NEXT */
  139.     {"mail",
  140.     "mail format",
  141.     "TEXT", mail_or_rmail_separator, mail_header_function, mail_date_function, mail_finish_header_function, 1},
  142.     {"mail_or_rmail",
  143.     "mail or rmail or both",
  144.     "TEXT", mail_or_rmail_separator, mail_header_function, mail_date_function, mail_finish_header_function, 1},
  145.     {"mail_digest",
  146.     "standard internet mail digest format",
  147.     "TEXT", mail_digest_separator_function, mail_header_function, mail_date_function, mail_finish_header_function, 1},
  148.     {"mh_bboard",
  149.     "MH bulletin board format",
  150.     "TEXT", mh_bboard_separator_function, mail_header_function, 0, mail_finish_header_function, 1},
  151.     {"rmail",
  152.     "rmail format",
  153.     "TEXT", rmail_separator_function, mail_header_function, mail_date_function, mail_finish_header_function, 1},
  154.     {"netnews",
  155.     "netnews format",
  156.     "TEXT", 0, mail_header_function, mail_date_function, mail_finish_header_function, 1},
  157.     {"rn",
  158.     "netnews saved by the [rt]?rn newsreader",
  159.     "TEXT", rn_separator_function, mail_header_function, mail_date_function, mail_finish_header_function, 1},
  160.     {"emacsinfo",
  161.     "the GNU documentation system",
  162.     "TEXT", emacs_info_separator_function, emacs_info_header_function, 0, emacs_info_finish_header_function, 1},
  163.     {"catalog",
  164.     "??",
  165.     "TEXT", catalog_separator_function, catalog_header_function, 0, catalog_finish_header_function, 1},
  166.     {"bio",
  167.     "biology abstract format",
  168.     "TEXT", bio_separator_function, bio_header_function, 0, bio_finish_header_function, 1},
  169.     {"cmapp",
  170.     "CM applications from Hypercard",
  171.     "TEXT", cmapp_separator_function, cmapp_header_function, 0, cmapp_finish_header_function, 1},
  172.     {"ftp",
  173.     "special type for FTP files.  First line of file is headline",
  174.     "TEXT", first_line_separator_function, first_line_header_function, 0, first_line_finish_header_function, 1},
  175.     {"jargon",
  176.     "Jargon File 2.9.8 format",
  177.     "TEXT", jargon_separator_function, jargon_header_function, 0, jargon_finish_header_function, 1},
  178.     {"server",
  179.     "server structures for the dir of servers",
  180.     "WSRC", 0, 0, 0, filename_finish_header_function},
  181.     {"text",
  182.     "simple text files, this is the default",
  183.     "TEXT", 0,0,0,0, 1},
  184.     {"filename",
  185.     "uses only the filename part of the pathname for the title",
  186.     "TEXT", 0,0,0, filename_finish_header_function, 1},
  187.     {"irg",
  188.     "internet resource guide",
  189.     "TEXT", irg_separator_function, irg_header_function, 0, irg_finish_header_function, 1},
  190.     {"dash",
  191.     "entries separated by a row of dashes",
  192.     "TEXT", dash_separator_function, dash_header_function, 0, dash_finish_header_function, 1},
  193.     {"one_line",
  194.     "each line is a document",
  195.     "TEXT", one_line_separator_function, one_line_header_function, 0, one_line_finish_header_function, 1},
  196.     {"para",
  197.     "paragraphs separated by blank lines",
  198.     "TEXT", para_separator_function, para_header_function, 0, para_finish_header_function, 1},
  199.     {"seeker",
  200.     "??",
  201.     "TEXT", seeker_separator_function, seeker_header_function, 0, seeker_finish_header_function, 1},
  202.     {"medline",
  203.     "medline format",
  204.     "TEXT", medline_separator_function, medline_header_function, 0, medline_finish_header_function, 1},
  205.     {"refer",
  206.     "refer format",
  207.     "TEXT", refer_separator_function, refer_header_function, 0, refer_finish_header_function, 1},
  208.     {"first_line",
  209.     "first line of file is headline",
  210.     "TEXT", first_line_separator_function, first_line_header_function, 0, first_line_finish_header_function, 1},
  211.     {"rlin",
  212.     "??",
  213.     "TEXT", rlin_separator_function, rlin_header_function, 0, rlin_finish_header_function, 1},
  214.     {"dvi",
  215.     "dvi format",
  216.     "DVI", 0, 0, 0, filename_finish_header_function, 1},
  217.     {"ps",
  218.     "postscript format ",
  219.     "PS", 0, 0, 0, filename_finish_header_function, 0},
  220.     {"pict",
  221.     "pict files, only indexes the filename",
  222.     "PICT", 0, 0, 0, filename_finish_header_function, 0},
  223.     {"gif",
  224.     "gif files, only indexes the filename",
  225.     "GIF", 0, 0, 0, filename_finish_header_function, 0},
  226.     {"tiff",
  227.     "tiff files, only indexes the filename",
  228.     "TIFF", 0, 0, 0, filename_finish_header_function, 0},
  229.     {"bibtex",
  230.     "BibTeX / LaTeX format",
  231.     "TEXT", bibtex_separator_function, bibtex_header_function, 0, bibtex_finish_header_function, 1},
  232.     {"nhyp",
  233.     "?:? hyper text format, Polytechnic of Central London",
  234.     "TEXT", nhyp_separator_function, nhyp_header_function, 0, nhyp_finish_header_function, 1},
  235.     {"ziff",
  236.     "ziff special format",
  237.     "TEXT", ziff_separator_function, ziff_header_function, 0, ziff_finish_header_function, 1},
  238. #ifdef /* sco */ M_UNIX
  239.     {"erg_mail_thread",
  240.     "SCO ERG mail thread format",
  241.     "TEXT",     erg_thread_separator_function, 
  242.         erg_thread_header_function, 
  243.             mail_date_function, 
  244.             erg_thread_finish_header_function, 1},
  245.     {"mmdf",
  246.     "MMDF mail folder format",
  247.     "TEXT",     mmdf_separator_function, 
  248.         mail_header_function, 
  249.         mail_date_function, 
  250.         mail_finish_header_function, 1},
  251.  
  252.     { "change_desc", 
  253.     "SCO ERG change descriptions format",
  254.     "TEXT", first_line_separator_function,  
  255.         erg_cd_header_function,
  256.         mail_date_function, /* fix this later, can look in the cd */
  257.         erg_cd_finish_header_function, 1},
  258. #endif
  259.     0
  260. };
  261.  
  262.  
  263. void usage(command)
  264. char *command;
  265. {
  266.  /* no args */
  267.   struct file_type *t;
  268.   int first;
  269.  
  270.   fprintf(stderr,"Usage: %s [-d index_filename]\n", command);
  271.   fprintf(stderr,"          [-a] /* adding to an existing index, otherwise it erases the index */\n");
  272.   fprintf(stderr,"          [-r] /* recursively index subdirectories */\n");
  273.   fprintf(stderr,"          [-mem mbytes] /* number of megabytes to run this in */\n");
  274.   fprintf(stderr,"          [-register] /* registers the database with the directory of servers.\n");
  275.   fprintf(stderr,"                         This should be done with care. */\n");
  276.   fprintf(stderr,"          [-export] /* uses short dbname and port 210 */\n");
  277.   fprintf(stderr,"          [-e [file]] /* set log output to file, or /dev/null if not specified */\n");
  278.   fprintf(stderr,"          [-f [filter]] /* run filter on each file before indexing */\n");
  279.   fprintf(stderr,"          [-l log_level] /* set log level.  0 means log nothing,\n");
  280.   fprintf(stderr,"                            10 [the default] means log everything */\n");
  281.   fprintf(stderr,"          [-v] /* print the version of the software */\n");
  282.   fprintf(stderr,"          [-stdin] /* read file names from stdin */\n");
  283.   fprintf(stderr,"          [-pos | -nopos] /* include (don't include - default) word position information /*\n");
  284.   fprintf(stderr,"          [-nopairs | -pairs] /* don't include (or include - default) word pairs /*\n");
  285.   fprintf(stderr,"          [-nocat] /* inhibit creation of catalog /*\n");
  286.   fprintf(stderr,"          [-contents] /* Index the contents: this is good for types that\n");
  287.   fprintf(stderr,"                         inhibit the indexing of the contents (like gif). /*\n");
  288.   fprintf(stderr,"          [-nocontents] /* Index only the filename, not the contents /*\n");
  289.   fprintf(stderr,"          [-cmmem  mem%] /* percent of CM memory (CM code only) */\n");
  290.   fprintf(stderr,"          [-T  type] /* type becomes the \"TYPE\" of the document. */\n");
  291.   fprintf(stderr,"          [-t    /* format of the file. if none then each file is a document */\n");
  292.   for (t=file_type_list, first=0; t->name; t++, first++) {
  293.       fprintf(stderr,"             %c %s /* %s */\n", first ? '|' : ' ', t->name, t->description);
  294.   }
  295. #if 0
  296.   fprintf(stderr,"             text /* simple text files, this is the default */\n");
  297.   fprintf(stderr,"           | bibtex /* BibTeX / LaTeX format */\n");
  298.   fprintf(stderr,"           | bio /* biology abstract format */\n");
  299.   fprintf(stderr,"           | cmapp /* CM applications from Hypercard */\n");
  300.   fprintf(stderr,"           | dash /* entries separated by a row of dashes */\n");
  301.   fprintf(stderr,"           | dvi /* dvi format */\n");     
  302.   fprintf(stderr,"           | emacsinfo /* the GNU documentation system */\n");
  303.   fprintf(stderr,"           | first_line /* first line of file is headline */\n");
  304.   fprintf(stderr,"           | filename /* uses only the filename part of the pathname for the title */\n");
  305.   fprintf(stderr,"           | ftp /* special type for FTP files.  First line of file is headline */\n");
  306.   fprintf(stderr,"           | gif /* gif files, only indexes the filename */\n");
  307.   fprintf(stderr,"           | irg /* internet resource guide */\n");
  308.   fprintf(stderr,"           | jargon /* Jargon File 2.9.8 format*/\n");
  309.   fprintf(stderr,"           | mail_digest /* standard internet mail digest format */\n");
  310.   fprintf(stderr,"           | mail_or_rmail /* mail or rmail or both */\n");
  311.   fprintf(stderr,"           | medline /* medline format */\n");
  312.   fprintf(stderr,"           | mh_bboard /* MH bulletin board format */\n");
  313.   fprintf(stderr,"           | netnews /* netnews format */\n");
  314.   fprintf(stderr,"           | nhyp /* ?:? hyper text format, Polytechnic of Central London */\n");
  315.   fprintf(stderr,"           | one_line /* each line is a document */\n");
  316.   fprintf(stderr,"           | para /* paragraphs separated by blank lines */\n");
  317.   fprintf(stderr,"           | pict /* pict files, only indexes the filename */\n");
  318.   fprintf(stderr,"           | ps /* postscript format */\n");
  319.   fprintf(stderr,"           | refer /* refer format */\n");
  320.   fprintf(stderr,"           | rn /* netnews saved by the [rt]?rn newsreader */\n");
  321.   fprintf(stderr,"           | server /* server structures for the dir of servers */\n");
  322. #ifdef NeXT
  323.   fprintf(stderr,"           | objc /* objective-C .h and .m files */\n");
  324. #endif /* def NeXT */
  325.   fprintf(stderr,"           | tiff /* tiff files, only indexes the filename */\n");
  326. #endif /* 0 */
  327.   fprintf(stderr,"          ] filename filename ...\n");
  328. }
  329.  
  330. char *log_file_name = NULL;
  331. FILE *logfile;
  332.  
  333. extern boolean index_contents;
  334. extern boolean filter_contents;
  335. extern char filter_program[];
  336.  
  337.  
  338. #define set(a,b) if (b) (a)=(b)
  339.  
  340. /* This is the MAIN for building an index.
  341.  */
  342. void
  343. main(argc, argv)
  344. int argc;
  345. char *argv[];
  346. {
  347.   database* db = NULL;
  348.   long argc_copy = argc;
  349.   char **argv_copy = argv;
  350.   char *next_argument;
  351.   char index_filename[1000];
  352.   boolean (*separator_function)();
  353.   void (*header_function)();
  354.   void (*finish_header_function)();
  355.   long (*date_function)();
  356.   boolean adding_to_existing_index = false;
  357.   boolean traverse_directory = false;
  358.   boolean word_positions = false;
  359.   boolean word_pairs = true;
  360.   long memory_to_use = -1;
  361.   long cm_mem_percent = 0;  /* default */
  362.   long grow_percent = 0;  /* default */
  363.   long text_size = 0;  /* default */
  364.   boolean check_for_text_file = false;
  365.   boolean register_database = false;
  366.   boolean export_database = false;
  367.   boolean read_files_from_stdin = false;
  368.   boolean make_catalog = true;
  369.   char data_filename[MAX_PATH_NAME_LEN];
  370.   char *typename = NULL;  /* this is what the user said */
  371.   char type[256];
  372. /*  char *type = NULL;      /* this is the type stored with the db */
  373.   long start_of_filenames;
  374.   long hashtable_size = 1L<<16;
  375.   long flush_after_n_words = 300000;
  376.   char *command_name;
  377.   struct file_type *t;
  378.  
  379.   next_argument = next_arg(&argc, &argv);
  380.   separator_function = NULL; /* initailize to nil */
  381.   header_function = NULL;
  382.   date_function = NULL;
  383.   finish_header_function = NULL;
  384. /*  type = "TEXT"; /* default to text */
  385.     strcpy(type, "TEXT");
  386.   typename = "Text"; 
  387.  
  388.   command_name = next_argument;
  389.  
  390.   logfile = stderr;
  391.   wais_pid = getpid();
  392.  
  393.   if(0 == argc) {
  394.     usage(command_name);
  395.     exit(0);
  396.   }
  397.  
  398. #ifdef THINK_C
  399.   strcpy(index_filename, "wais:System Folder:wais-index:index");
  400. #else
  401.   strcpy(index_filename, "index"); /* in the current directory */
  402. #endif /* THINK_C */
  403.   
  404.   if(NULL == (next_argument = next_arg(&argc, &argv))){
  405.     fprintf(stderr,"No arguments specified\n");
  406.     exit(0);
  407.   }
  408.   while((next_argument != NULL) && '-' == next_argument[0]){
  409.     /* then we have an argument to process */
  410.     if((0 == strcmp("-i", next_argument)) || /* -i is for backcompatibility */
  411.        (0 == strcmp("-d", next_argument))){
  412.       if(NULL == (next_argument = next_arg(&argc, &argv))){
  413.     fprintf(stderr,"Expected filename for the index\n");
  414.     exit(0);
  415.       }
  416.       strcpy(index_filename, next_argument);
  417.       }
  418.     else if(0 == strcmp("-a", next_argument)){
  419.       adding_to_existing_index = true;
  420.     }
  421.     else if(0 == strcmp("-r", next_argument)){
  422.       traverse_directory = true;
  423.     }
  424.     else if(0 == strcmp("-register", next_argument)){
  425.       register_database = true;
  426.     }
  427.     else if(0 == strcmp("-export", next_argument)){
  428.       export_database = true;
  429.     }
  430.     else if(0 == strcmp("-f", next_argument)){
  431.       if(NULL == (next_argument = next_arg(&argc, &argv))){
  432.     fprintf(stderr,"Expected filter for -f\n");
  433.     exit(1);
  434.       }
  435.       strcpy(filter_program, next_argument);
  436.       filter_contents = TRUE;
  437.     }
  438.     else if(0 == strcmp("-v", next_argument)){
  439.       fprintf(stderr,"%s: %s\n", command_name, VERSION, INDEXER_DATE);
  440.     }
  441.     else if (0 == strcmp("-stdin", next_argument)) {
  442.       read_files_from_stdin = true;
  443.     }
  444.     else if (0 == strcmp("-nopos", next_argument)) {
  445.       word_positions = false;
  446.     }
  447.     else if (0 == strcmp("-pos", next_argument)) {
  448.       word_positions = true;
  449.     }
  450.     else if (0 == strcmp("-nopairs", next_argument)) {
  451.       word_pairs = false;
  452.     }
  453.     else if (0 == strcmp("-pairs", next_argument)) {
  454.       word_pairs = true;
  455.     }
  456.     else if (0 == strcmp("-nocat", next_argument)) {
  457.       make_catalog = false;
  458.     }
  459.     else if(0 == strcmp("-mem", next_argument)){
  460.       if(NULL == (next_argument = next_arg(&argc, &argv)))
  461.     panic("Expected a number for the amount of memory to use");
  462.       memory_to_use = atol(next_argument);
  463.       if(memory_to_use < 1)
  464.     panic("The -mem argument should not be less than 1");
  465.       if(memory_to_use > 200)
  466.     fprintf(stderr,"Warning: The -mem parameter was %ld Mbytes.  That is a large number of mega bytes in current machines\n", memory_to_use);
  467.     }
  468.     else if(0 == strcmp("-cmmem", next_argument)){
  469.       if(NULL == (next_argument = next_arg(&argc, &argv)))
  470.     panic("Expected a number (1-100) for percentage of memory to use");
  471.       cm_mem_percent = atol(next_argument);
  472.       if(cm_mem_percent < 1)
  473.     panic("The -cmmem argument should not be less than 1 and less than 100");
  474.       if(cm_mem_percent > 100)
  475.     panic("Warning: The -cmmem parameter was %ld%%. It should be between 1-100.", cm_mem_percent);
  476.     }
  477.     else if(0 == strcmp("-grow", next_argument)){
  478.       if(NULL == (next_argument = next_arg(&argc, &argv)))
  479.         panic("Expected a number (1-100) for database growing percentage");
  480.       grow_percent = atol(next_argument);
  481.       if(grow_percent < 1)
  482.         panic("The -grow argument should not be less than 1");
  483.     }
  484.     else if(0 == strcmp("-textsize", next_argument)){
  485.       if(NULL == (next_argument = next_arg(&argc, &argv)))
  486.         panic("Expected a number for text size in megabytes");
  487.       text_size = atol(next_argument);
  488.       if(text_size < 1)
  489.         panic("The -textsize argument should not be less than 1");
  490.     }
  491.     else if (0 == strcmp("-e", next_argument)) {
  492.       char *peek_argument = peek_arg(&argc, &argv);
  493.       log_file_name = "/dev/null"; /* default to /dev/null */
  494.       if ((peek_argument != NULL) &&
  495.       ('-' != peek_argument[0])) {
  496.     log_file_name = next_arg(&argc, &argv);
  497.       }                /* end if (explicit log file) */
  498.     }                /* end if (-e) */
  499.     else if (0 == strcmp("-l", next_argument)) {
  500.       wais_log_level = atol(next_arg(&argc, &argv));
  501.     }                /* end if (-l) */
  502.     else if(0 == strcmp("-cm", next_argument)){
  503.       /* this is an undocumented argument to help use this to
  504.      front end the CM application */
  505.       indexingForBeta = true;
  506.     }
  507.     else if(0 == strcmp("-T", next_argument)){
  508.       /* This is a specification for a "Special" type.  The next argument
  509.      is the type name.  This will not index the body of the file. */
  510.       if(NULL == (next_argument = next_arg(&argc, &argv)))
  511.     panic("Expected a file type");
  512.       typename = next_argument;
  513. /*      type = next_argument;*/
  514.       strcpy(type, next_argument);
  515.       finish_header_function = filename_finish_header_function;
  516.     }
  517.     else if(0 == strcmp("-contents", next_argument)){
  518.       index_contents = true;
  519.     }
  520.     else if(0 == strcmp("-nocontents", next_argument)){
  521.       index_contents = false;
  522.     }
  523.     else if(0 == strcmp("-t", next_argument)){
  524.       /* then we have a specialized file */
  525.       index_contents = true;
  526.       if(NULL == (next_argument = next_arg(&argc, &argv)))
  527.     panic("Expected a file type");
  528.       for(t = file_type_list; t->name; t++) {
  529.       if (strcmp(t->name, next_argument) == 0) {
  530.           typename = t->name;
  531.           strcpy(type, t->type);
  532.           set(separator_function, t->separator_function);
  533.           set(header_function, t->header_function);
  534.           set(date_function, t->date_function);
  535.           set(finish_header_function, t->finish_header_function);
  536.           set(index_contents, t->index_contents);
  537.           goto found;
  538.       }
  539.       }
  540.       panic("Don't recognize the '%s' type", next_argument);
  541.  
  542. found:
  543.       ;
  544.  
  545. #if 0
  546.       if(0 == strcmp("groliers", next_argument)){
  547.     typename = next_argument;
  548.     type = "TEXT";
  549.     separator_function = groliers_separator_function;
  550.     header_function = groliers_header_function;
  551.     finish_header_function = groliers_finish_header_function;
  552.       }
  553. #ifdef NeXT
  554.       else if(0 == strcmp("objc", next_argument)){
  555.     typename = next_argument;
  556.     type = "TEXT";
  557.     separator_function = wobjc_separator_function;
  558.     header_function = wobjc_header_function;
  559.     finish_header_function = wobjc_finish_header_function;
  560.       }
  561. #endif /* def NeXT */
  562.       else if(0 == strcmp("mail", next_argument)){
  563.     typename = next_argument;
  564.     type = "TEXT";
  565.     separator_function = mail_separator_function;
  566.     header_function = mail_header_function;
  567.     date_function = mail_date_function;
  568.     finish_header_function = mail_finish_header_function;
  569.       }
  570.       else if(0 == strcmp("erg_mail_thread", next_argument)){
  571.     typename = next_argument;
  572.     type = "TEXT";
  573.     separator_function = erg_thread_separator_function;
  574.     header_function = erg_thread_header_function;
  575.     date_function = mail_date_function;
  576.     finish_header_function = erg_thread_finish_header_function;
  577.       }
  578.       else if(0 == strcmp("mail_or_rmail", next_argument)){
  579.     typename = next_argument;
  580.     type = "TEXT";
  581.     separator_function = mail_or_rmail_separator;
  582.     header_function = mail_header_function;
  583.     date_function = mail_date_function;
  584.     finish_header_function = mail_finish_header_function;
  585.       }
  586.       else if(0 == strcmp("mail_digest", next_argument)){
  587.     typename = next_argument;
  588.     type = "TEXT";
  589.     separator_function = mail_digest_separator_function;
  590.      header_function = mail_header_function;
  591.      date_function = mail_date_function;
  592.      finish_header_function = mail_finish_header_function;
  593.       }
  594.       else if(0 == strcmp("mh_bboard", next_argument)){
  595.      typename = next_argument;
  596.      type = "TEXT";
  597.      separator_function = mh_bboard_separator_function;
  598.     header_function = mail_header_function;
  599.     date_function = mail_date_function;
  600.     finish_header_function = mail_finish_header_function;
  601.       }
  602.       else if(0 == strcmp("rmail", next_argument)){
  603.     typename = next_argument;
  604.     type = "TEXT";
  605.     separator_function = rmail_separator_function;
  606.     header_function = mail_header_function;
  607.     date_function = mail_date_function;
  608.     finish_header_function = mail_finish_header_function;
  609.       }
  610.       else if(0 == strcmp("netnews", next_argument)){
  611.     typename = next_argument;
  612.     type = "TEXT";
  613.     separator_function = NULL;
  614.     header_function = mail_header_function;
  615.     date_function = mail_date_function;
  616.     finish_header_function = mail_finish_header_function;
  617.       }
  618.       else if(0 == strcmp("rn", next_argument)){
  619.     typename = next_argument;
  620.     type = "TEXT";
  621.     separator_function = rn_separator_function;
  622.     header_function = mail_header_function;
  623.     date_function = mail_date_function;
  624.     finish_header_function = mail_finish_header_function;
  625.       }
  626.       else if(0 == strcmp("emacsinfo", next_argument)){
  627.     typename = next_argument;
  628.     type = "TEXT";
  629.     separator_function = emacs_info_separator_function;
  630.     header_function = emacs_info_header_function;
  631.     finish_header_function = emacs_info_finish_header_function;
  632.       }
  633.       else if(0 == strcmp("catalog", next_argument)){
  634.     typename = next_argument;
  635.     type = "TEXT";
  636.     separator_function = catalog_separator_function;
  637.     header_function = catalog_header_function;
  638.     finish_header_function = catalog_finish_header_function;
  639.       }
  640.       else if(0 == strcmp("bio", next_argument)){
  641.     typename = next_argument;
  642.     type = "TEXT";
  643.     separator_function = bio_separator_function;
  644.     header_function = bio_header_function;
  645.     finish_header_function = bio_finish_header_function;
  646.       }
  647.       else if(0 == strcmp("cmapp", next_argument)){
  648.     typename = next_argument;
  649.     type = "TEXT";    
  650.     separator_function = cmapp_separator_function;
  651.     header_function = cmapp_header_function;
  652.     finish_header_function = cmapp_finish_header_function;
  653.       }
  654.       else if(0 == strcmp("ftp", next_argument)){
  655.     type = "TEXT-FTP";
  656.     typename = next_argument;
  657.     separator_function = first_line_separator_function;
  658.     header_function = first_line_header_function;
  659.     finish_header_function = first_line_finish_header_function;
  660.       }
  661.       else if(0 == strcmp("jargon", next_argument)){
  662.     typename = next_argument;
  663.     type = "TEXT";
  664.     separator_function = jargon_separator_function;
  665.     header_function = jargon_header_function;
  666.     finish_header_function = jargon_finish_header_function;
  667.       }
  668.       else if(0 == strcmp("server", next_argument)){
  669.     typename = next_argument;
  670.     type = "WSRC";
  671.     finish_header_function = filename_finish_header_function;
  672.       }
  673.       else if(0 == strcmp("text", next_argument)){
  674.     type = "TEXT";
  675.     typename = next_argument;
  676.     check_for_text_file = true;
  677.       }
  678.       else if(0 == strcmp("filename", next_argument)){
  679.     type = "TEXT";
  680.     typename = next_argument;
  681.     finish_header_function = filename_finish_header_function;
  682.       }
  683.       else if(0 == strcmp("irg", next_argument)){
  684.     typename = next_argument;
  685.     type = "TEXT";
  686.     separator_function = irg_separator_function;
  687.     header_function = irg_header_function;
  688.     finish_header_function = irg_finish_header_function;
  689.       }
  690.       /* dash-separated items , Intro to Algorithms buglist, etc */
  691.       else if(0 == strcmp("dash", next_argument)){
  692.     type = "TEXT";
  693.     typename = next_argument;
  694.     separator_function = dash_separator_function;
  695.     header_function = dash_header_function;
  696.     finish_header_function = dash_finish_header_function;
  697.       }
  698.       /* one_line-separated items */
  699.       else if(0 == strcmp("one_line", next_argument)){
  700.     type = "TEXT";
  701.     typename = next_argument;
  702.     separator_function = one_line_separator_function;
  703.     header_function = one_line_header_function;
  704.     finish_header_function = one_line_finish_header_function;
  705.       }
  706.       /* blank line-separated items (paragraphs) */
  707.       else if(0 == strcmp("para", next_argument)){
  708.     type = "TEXT";
  709.     typename = next_argument;
  710.     separator_function = para_separator_function;
  711.     header_function = para_header_function;
  712.     finish_header_function = para_finish_header_function;
  713.       }
  714.       /* seeker items */
  715.       else if(0 == strcmp("seeker", next_argument)){
  716.     type = "TEXT";
  717.     typename = next_argument;
  718.     separator_function = seeker_separator_function;
  719.     header_function = seeker_header_function;
  720.     finish_header_function = seeker_finish_header_function;
  721.       }
  722.       /* medline format */
  723.       else if(0 == strcmp("medline", next_argument)){
  724.     type = "TEXT";
  725.     typename = next_argument;
  726.     separator_function = medline_separator_function;
  727.     header_function = medline_header_function;
  728.     finish_header_function = medline_finish_header_function;
  729.       }
  730.       /* refer format */
  731.       else if(0 == strcmp("refer", next_argument)){
  732.     type = "TEXT";
  733.     typename = next_argument;
  734.     separator_function = refer_separator_function;
  735.     header_function = refer_header_function;
  736.     finish_header_function = refer_finish_header_function;
  737.       }
  738.       /* first_line format */
  739.       else if(0 == strcmp("first_line", next_argument)){
  740.     type = "TEXT";
  741.     typename = next_argument;
  742.     separator_function = first_line_separator_function;
  743.     header_function = first_line_header_function;
  744.     finish_header_function = first_line_finish_header_function;
  745.       }
  746.       /* rlin items */
  747.       else if(0 == strcmp("rlin", next_argument)){
  748.     type = "TEXT";
  749.     typename = next_argument;
  750.     separator_function = rlin_separator_function;
  751.     header_function = rlin_header_function;
  752.     finish_header_function = rlin_finish_header_function;
  753.       }
  754.       else if(0 == strcmp("dvi", next_argument)){
  755.     typename = next_argument;
  756.     type = "DVI";
  757.     finish_header_function = filename_finish_header_function;
  758.       }
  759.       else if(0 == strcmp("ps", next_argument)){
  760.     typename = next_argument;
  761.     type = "PS";
  762.     finish_header_function = filename_finish_header_function;
  763.       }
  764.       else if(0 == strcmp("pict", next_argument)){
  765.     typename = next_argument;
  766.     type = "PICT";    
  767.     finish_header_function = filename_finish_header_function;
  768.     index_contents = false;
  769.       }
  770.       else if(0 == strcmp("gif", next_argument)){
  771.     typename = next_argument;
  772.     type = "GIF";    
  773.     finish_header_function = filename_finish_header_function;
  774.     index_contents = false;
  775.       }
  776.       else if(0 == strcmp("tiff", next_argument)){
  777.     typename = next_argument;
  778.     type = "TIFF";    
  779.     finish_header_function = filename_finish_header_function;
  780.     index_contents = false;
  781.       }
  782.       /* BibTeX items */
  783.       else if(0 == strcmp("bibtex", next_argument)){
  784.     type = "TEXT";
  785.     typename = next_argument;
  786.     separator_function = bibtex_separator_function;
  787.     header_function = bibtex_header_function;
  788.     finish_header_function = bibtex_finish_header_function;
  789.       }
  790.       /* ?:? seperated hypertext items */
  791.       else if(0 == strcmp("nhyp", next_argument)){
  792.     type = "TEXT";
  793.     typename = next_argument;
  794.     separator_function = nhyp_separator_function;
  795.     header_function = nhyp_header_function;
  796.     finish_header_function = nhyp_finish_header_function;
  797.       }
  798.       else if(0 == strcmp("ziff", next_argument)){
  799.     type = "TEXT";
  800.     typename = next_argument;
  801.     separator_function = ziff_separator_function;
  802.     header_function = ziff_header_function;
  803.     finish_header_function = ziff_finish_header_function;
  804.       }
  805.       else{
  806.     panic("Don't recognize the '%s' type", next_argument);
  807.       }
  808. #endif /* 0 */
  809.     }
  810.     else{
  811.       panic("Don't recognize the '%s' option", next_argument);
  812.     }
  813.  
  814.     next_argument = next_arg(&argc, &argv);
  815.     if (! (read_files_from_stdin || next_argument)) {
  816.       fprintf(stderr,"No files specified\n");
  817.       exit(0);
  818.     }
  819.   }
  820.   start_of_filenames = argc_copy - argc - 1;
  821.  
  822.   /* check index */
  823.   if(0 == strlen(pathname_name(index_filename))){
  824.     waislog(WLOG_HIGH, WLOG_ERROR,
  825.         "The pathname specified for the destination of the index files ('%s') should have a leaf filename without an extention rather than just a directory.",
  826.         index_filename);
  827.     exit(0);     
  828.   }
  829.     
  830.   waislog(WLOG_MEDIUM, WLOG_INDEX, "Starting to build database %s",
  831.       index_filename);
  832.  
  833.   if(0 != init_search_engine(index_filename, false, false, cm_mem_percent,
  834.           text_size, grow_percent))
  835.     panic("unable to initialize search engine");
  836.  
  837.   if(true == adding_to_existing_index){
  838.     db = openDatabase(index_filename, false, false);
  839.     if (db == NULL){ /* does not exist, create one */
  840.       db = openDatabase(index_filename, true, false);
  841.       if (db == NULL)
  842.     panic("unable to open the database");
  843.     }
  844.   }
  845.   else{
  846.     db = openDatabase(index_filename, true, false);
  847.     if (db == NULL)
  848.       panic("unable to open the database");
  849.   }
  850.   { /* set up the memory hashtable */
  851.  
  852.     if(memory_to_use < 0){ /* default */
  853.       /* do nothing */
  854.     }
  855.     else if(memory_to_use <= 2){
  856.       hashtable_size = 1L<<16;
  857.       flush_after_n_words = 50000;
  858.     }
  859.     else if(memory_to_use <= 5){
  860.       hashtable_size = 1L<<16;
  861.       flush_after_n_words = 150000;
  862.     }
  863.     else if(memory_to_use <= 10){
  864.       /* shown to take about 6MB on a sun4, when it is dict limited */
  865.       hashtable_size = 1L<<16;
  866.       flush_after_n_words = 300000;
  867.     }
  868.     else if(memory_to_use <= 20){
  869.       hashtable_size = 1L<<17;
  870.       flush_after_n_words = 600000;
  871.     }
  872.     else{ /* over 20 Mbytes */
  873.       hashtable_size = 1L<<18;
  874.       flush_after_n_words = 1000000;
  875.     }
  876.     init_add_word(db, hashtable_size, flush_after_n_words);
  877.   }
  878.  
  879.   if (read_files_from_stdin) {
  880.     if (0 != (next_argument = fgets(data_filename, MAX_PATH_NAME_LEN, stdin))) {
  881.       int len = strlen(next_argument);
  882.       if (next_argument[len-1] == '\n') {
  883.     next_argument[len-1] = '\0';
  884.       }
  885.     }
  886.   }
  887.  
  888.   while(NULL != next_argument){ /* the first filename is in next_argument already */
  889.     if(directoryp(next_argument)){
  890.        if(traverse_directory){
  891.      index_directory(next_argument,
  892.              separator_function,
  893.              header_function,
  894.              date_function,
  895.              finish_header_function,
  896.              type, db,
  897.              check_for_text_file,
  898.              adding_to_existing_index, 
  899.              word_positions, word_pairs);
  900.        }
  901.      }
  902.     else{            /* not a directory */
  903.       waislog(WLOG_MEDIUM, WLOG_INDEX, 
  904.           "Indexing file: %s", next_argument);
  905.       index_text_file(next_argument,
  906.               separator_function,
  907.               header_function,
  908.               date_function,
  909.               finish_header_function,
  910.               type, db, 
  911.               check_for_text_file, adding_to_existing_index,
  912.               word_positions, word_pairs);
  913.     }
  914.     if (read_files_from_stdin) {
  915.       if (0 != (next_argument = fgets(data_filename, MAX_PATH_NAME_LEN, stdin))) {
  916.     int len = strlen(next_argument);
  917.     if (next_argument[len-1] == '\n') {
  918.       next_argument[len-1] = '\0';
  919.     }
  920.       }
  921.     }
  922.     else {
  923.       next_argument = next_arg(&argc, &argv);
  924.     }
  925.   }
  926.   finished_add_word(db);
  927.   {
  928.     char filename[MAX_FILENAME_LEN + 1];
  929.     if(!probe_file(source_filename(filename, db))){
  930.       char database_name[MAX_FILENAME_LEN];
  931.       write_src_structure(source_filename(filename, db),
  932.               export_database?pathname_name(index_filename):
  933.                       truename(index_filename, database_name),
  934.               typename,
  935.               &argv_copy[start_of_filenames],
  936.               argc_copy - start_of_filenames,
  937.               export_database,
  938.               210L);
  939.     }
  940.     /* write out a description of the server if appropriate */
  941.     if(register_database){
  942.       register_src_structure(source_filename(filename, db));
  943.     }
  944.   }
  945.   if(make_catalog) build_catalog(db);
  946.   closeDatabase(db);
  947.   waislog(WLOG_MEDIUM, WLOG_INDEX, "Finished build");
  948.   exit(0);
  949. }
  950.